using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.Collections.Specialized;

namespace MessageLibrary
{
    public class ActiveClients : IDisposable
    {
        #region Data members and events
        /// <summary>
        /// a generic list that contains all the
        /// current connescted client to the server
        /// </summary>
        List<Client> arr = new List<Client>();

        public delegate void CollectionChnagedEventHandler(List<Client> arr);
        public delegate void ChangeEventHandler(Client c);
        /// <summary>
        /// An event that occurs when the array was changed
        /// </summary>
        public event CollectionChnagedEventHandler Changed;
        /// <summary>
        /// An event that occurs when a client was added         
        /// </summary>
        public event ChangeEventHandler Added;
        /// <summary>
        /// An event that occurs when a client was removed         
        /// </summary>
        public event ChangeEventHandler Removed;

        # endregion


        public ActiveClients()
        {
            
        }

        /// <summary>
        /// Adds a client to the array
        /// </summary>
        /// <param name="client">the cilent to add</param>
        public void Add(Client client)
        {
            
            if (client!=null)
            {
                //add the client            
                arr.Add(client);
                //informs the server about the change
                if (Changed != null) { Changed(arr); }
                if (Added != null) Added(client);
            }
            
        }
        /// <summary>
        /// checks if the client has been added to 
        /// the array
        /// </summary>
        /// <param name="c">client to check</param>
        /// <returns>answer value</returns>
        public bool Contains(Client c)
        {
            if (c!=null)
            {
                return arr.Contains(c);
            }
            return false;
        }

        /// <summary>
        /// checks if he user name already exist in the clients array
        /// </summary>
        /// <param name="name">name to check</param>
        /// <returns>bool - true for exists</returns>
        public bool CheckName(string name)
        {
            for (int i = 0; i < arr.Count - 1; i++)
            {
                if (arr[i].UserName == name)
                {
                    return true;
                    
                }
            }
            
            return false;
        }

        /// <summary>
        /// removes a given client from the array by 
        /// a given user name
        /// </summary>
        /// <param name="name">user name</param>
        /// <returns>validation parameter</returns>
        public bool Remove(string name)
        {            
            //searches array for client
            foreach (Client c in arr)
            {
                if (c.UserName==name)
                {
                    //removes client and return true for validation
                    arr.Remove(c);
                    //informs the server about the change
                    if (Changed != null) { Changed(arr); }
                    if (Removed != null) Removed(c);
                    return true;
                }
            }
            //return false if the client is not in the array
            return false;
        }
        /// <summary>
        /// removes a given client from the array
        /// </summary>
        /// <param name="c">client to remove</param>
        /// <returns>validation parameter</returns>
        public bool Remove(Client c)
        {            
            bool flag=arr.Remove(c);
            //informs the server about the change
            if (flag && Removed != null) Removed(c);            
            if (flag && Changed!=null)
            {
                Changed(arr);
            }
            return flag;
        }

        /// <summary>
        /// returns the number of the client
        /// in the array
        /// </summary>
        public int Count
        {
            get { return arr.Count; }
        }

        /// <summary>
        /// an indexer that returns a client by 
        /// it's location in the array
        /// </summary>
        /// <param name="index">location in array</param>
        /// <returns>client</returns>
        public Client this[int index]
        {
            get { return arr[index]; }
            
        }
	
        /// <summary>
        /// an indexer that returns a client by
        /// it's user name
        /// </summary>
        /// <param name="name">user name of wanted client</param>
        /// <returns>client</returns>
        public Client this[string name]
        {
            get
            {
                for (int i = 0; i < arr.Count-1; i++)
                {
                    if (arr[i].UserName==name)
                    {
                        return arr[i];
                    }
                }
                return null;
            }              
            
        }

        /// <summary>
        /// stops all running clients in the array
        /// </summary>
        public void StopArray()
        {
            foreach (Client c in arr)
            {
                c.Stop();
            }
        }



        #region IDisposable Members

        void IDisposable.Dispose()
        {
            foreach (Client c in arr)
            {
                c.Stop();

            }
            arr.Clear();
            GC.ReRegisterForFinalize(arr);
            GC.ReRegisterForFinalize(this);
        }

        #endregion
    }
}
